import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import com.sun.org.apache.xerces.internal.impl.xs.SchemaNamespaceSupport;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: DELL
 * Date: 2023-03-21
 * Time: 10:40
 */
public class JDBCInsertDemo {
    public static void main(String[] args) throws SQLException {
        // 使用 jdbc 往数据中插入一个记录
        // 需要提前准备好数据库(库名) -- 0321

        // DataSource 相比于 DriverManager 内置了数据库连接池, 可以重复利用连接
        // DriverManager 使用的时候需要借助反射, 反射不属于常规编程手段

        // 1. 创建数据源, 描述了服务器在哪儿
        //    驱动包中提供的具体类
        DataSource dataSource = new MysqlDataSource(); // 向上转型 DataSource里包括了MysqlDataSource
        ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java0321?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("lyf2021");
        //    向下转型 避免后续使用 DataSource 扩散
        // 2. 和数据库建立网络连接,(写 jdbc 代码本质上实现一个 mysql 客户端, 通过网络和服务器进行通信
        //    "连接操作" 才是真正的开始网络通信
        //     Connection 选择 java.sql 包下的
        Connection connection = dataSource.getConnection();

        // 通过控制台来输入用户信息(动态 sql 构造)
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入学号: ");
        int id = scanner.nextInt();
        System.out.println("请输入姓名: ");
        String name = scanner.next();

        // 3. 构建一个 sql 语句, 来完成插入操作
        String sql = "insert into student values(?, ?)";

        // jdbc 中 还需要搭配一个特定对象来描述这里的 sql 情况
        // preparedStatement 来执行具体 sql 语句 会对 sql 语句进行预处理比如解析
        PreparedStatement statement = connection.prepareStatement(sql);
                                           // TODO: 占位符 从 1 开始
        statement.setInt(1,id); // id 以整数的形式替换第一个占位符
        statement.setString(2,name); // name 以字符串的形式替换第二个占位符
        System.out.println("sql : " + statement);
        // 4. 执行 sql 语句 (控制客户端服务器发送请求)
        // 执行操作, 给服务器发送网络请求, 针对 增 删 改 使用 executeUpdate
        //         针对 查 使用 executeQuery
        int ret = statement.executeUpdate();
        System.out.println(ret);
        //   ret 结果表示 有几行受到此次 sql 语句影响
        // 5. 断开和数据库的连接, 并释放必要的资源
        // 资源释放顺序和创建顺序相反 先创建 connection 后 创建 statement
        statement.close();
        connection.close();
    }
}
